﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IRC.IRepairClouds.DataLayer
{
    public static class Converter
    {
        public const string IfNull = "N/A";

        public static string IfNullStr<T>(T val, Func<T, string> conv)
        {
            return IfNullStr<T>(val, conv, IfNull);
        }

        public static string IfNullStr<T>(T val, Func<T, string> conv, string ifNull)
        {
            if (conv == null)
                throw new ArgumentNullException("conv");
            return val != null ? conv(val) : ifNull;
        }

        public static string CBoolToStr(this bool? val)
        {
            return IfNullStr(val, i => CBoolToStr(i.Value));
        }
        public static string CBoolToStr(this bool? val, string ifNull)
        {
            return IfNullStr(val, i => CBoolToStr(i.Value), ifNull);
        }
        public static string CBoolToStr(this bool val)
        {
            return val ? "Yes" : "No";
        }


        public static string CFlagToStr(this int? val)
        {
            return IfNullStr(val, i => CFlagToStr(i.Value));
        }
        public static string CFlagToStr(this int? val, string ifNull)
        {
            return IfNullStr(val, i => CFlagToStr(i.Value), ifNull);
        }
        public static string CFlagToStr(this int val)
        {
            return val.Flag() ? "Yes" : "No";
        }

        public static string CDateToStr(this DateTime? val)
        {
            return IfNullStr(val, i => CDateToStr(i.Value));
        }
        public static string CDateToStr(this DateTime? val, string ifNull)
        {
            return IfNullStr(val, i => CDateToStr(i.Value), ifNull);
        }
        public static string CDateToStr(this DateTime val)
        {
            return val.ToString();
        }

        public static string CDateToStrFormat(this DateTime? val, string format)
        {
            return IfNullStr(val, i => CDateToStrFormat(i.Value, format));
        }
        public static string CDateToStrFormat(this DateTime? val, string format, string ifNull)
        {
            return IfNullStr(val, i => CDateToStrFormat(i.Value, format), ifNull);
        }
        public static string CDateToStrFormat(this DateTime val, string format)
        {
            if (!string.IsNullOrEmpty(format))
                return val.ToString(format);
            return val.ToString();
        }

        public static string CDateToStrDay(this DateTime? val)
        {
            return IfNullStr(val, i => CDateToStrDay(i.Value));
        }
        public static string CDateToStrDay(this DateTime? val, string ifNull)
        {
            return IfNullStr(val, i => CDateToStrDay(i.Value), ifNull);
        }
        public static string CDateToStrDay(this DateTime val)
        {
            return CDateToStrFormat(val, "d");
        }


        public static string CPercentToStr(this double? val)
        {
            return IfNullStr(val, i => CPercentToStr(i.Value));
        }
        public static string CPercentToStr(this double? val, string ifNull)
        {
            return IfNullStr(val, i => CPercentToStr(i.Value), ifNull);
        }
        public static string CPercentToStr(this double val)
        {
            return val.ToString("###,###,##0.00 '%'");
        }


        public static string CCurrToStr(this decimal? val)
        {
            return IfNullStr(val, i => CCurrToStr(i.Value));
        }
        public static string CCurrToStr(this decimal? val, string ifNull)
        {
            return IfNullStr(val, i => CCurrToStr(i.Value), ifNull);
        }
        public static string CCurrToStr(this decimal val)
        {
            return val.ToString("###,###,##0.00");
        }

        public enum CurrencySymbolPosition
        {
            Beginning,
            BeginningWithSpace,
            End,
            EndWithSpace
        }

        public static string CCurrToStrWithSymbol(this decimal? val, string symbol)
        {
            return CCurrToStrWithSymbol(val, symbol, CurrencySymbolPosition.EndWithSpace);
        }
        public static string CCurrToStrWithSymbol(this decimal? val, string symbol, string ifNull)
        {
            return CCurrToStrWithSymbol(val, symbol, CurrencySymbolPosition.EndWithSpace, ifNull);
        }
        public static string CCurrToStrWithSymbol(this decimal val, string symbol)
        {
            return CCurrToStrWithSymbol(val, symbol, CurrencySymbolPosition.EndWithSpace);
        }

        public static string CCurrToStrWithSymbol(this decimal? val, string symbol, CurrencySymbolPosition position)
        {
            return IfNullStr(val, i => CCurrToStrWithSymbol(i.Value, symbol, position));
        }
        public static string CCurrToStrWithSymbol(this decimal? val, string symbol, CurrencySymbolPosition position, string ifNull)
        {
            return IfNullStr(val, i => CCurrToStrWithSymbol(i.Value, symbol, position), ifNull);
        }
        public static string CCurrToStrWithSymbol(this decimal val, string symbol, CurrencySymbolPosition position)
        {
            if (symbol != null) {
                switch (position) {
                    case CurrencySymbolPosition.Beginning:
                        return symbol + val.CCurrToStr();
                    case CurrencySymbolPosition.BeginningWithSpace:
                        return symbol + " " + val.CCurrToStr();
                    case CurrencySymbolPosition.End:
                        return val.CCurrToStr() + symbol;
                    case CurrencySymbolPosition.EndWithSpace:
                        return val.CCurrToStr() + " " + symbol;
                }
            }
            return val.CCurrToStr();
        }


        public static string CStrToShortStr(this string val)
        {
            if (val != null && val.Length > 13)
                return val.Substring(0, 13) + "...";
            else
                return val;
        }

        //public static string CStrToShortStr(this string val, string addSymbol)
        //{
        //    if (val != null && val.Length > 0)
        //        return addSymbol + val.CStrToShortStr();
        //    else
        //        return val.CStrToShortStr();

        //}

        public static string CStrToStr(this string val)
        {
            return IfNullStr(val, i => i);
        }

        public static string CStrToStr(this string val, string ifNull)
        {
            return IfNullStr(val, i => i, ifNull);
        }

        public static string CIntToStr(this int? val)
        {
            return IfNullStr(val, i => CIntToStr(i.Value));
        }
        public static string CIntToStr(this int? val, string ifNull)
        {
            return IfNullStr(val, i => CIntToStr(i.Value), ifNull);
        }
        public static string CIntToStr(this int val)
        {
            return val.ToString();
        }


        public static string ToDimensions(int? length, int? width, int? height)
        {
            if (length == null && width == null && height == null)
                return null;
            return string.Format("{0} x {1} x {2}", length, width, height);
        }


        public static string ToShortAddress(string company, string city, string zip, string street)
        {
            StringBuilder sb = new StringBuilder();
            ToShortAddressAddField(sb, company);
            ToShortAddressAddField(sb, city);
            ToShortAddressAddField(sb, zip);
            ToShortAddressAddField(sb, street);
            return sb.ToString();
        }

        private static void ToShortAddressAddField(StringBuilder sb, string field)
        {
            if (!string.IsNullOrEmpty(field)) {
                if (sb.Length > 0)
                    sb.Append(" | ");
                sb.Append(field.CStrToShortStr());
            }
        }
    }
}
